﻿using pcEntity;
using pcObjectLibrary;
using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Linq;

namespace pcDAL
{
    public class PunchDAL
    {
        public PunchObjectLibrary opUserOpenLog(int opUserId)
        {
            PunchObjectLibrary log = new PunchObjectLibrary();
            using (var context = new PunchClockEntities())
            {
                log = (from p in context.tPunches
                        where p.userId == opUserId
                        && p.punchOut == null
                        select new PunchObjectLibrary
                        {
                            isManagerAccepted = p.isManagerAccepted,
                            punchDate = p.punchDate,
                            punchId = p.punchId,
                            punchIn = p.punchIn,
                            punchOut = p.punchOut,
                            userId = p.userId
                           
                        }).FirstOrDefault();
            }
            return log;
        }

        public List<PunchObjectLibrary> GetOpenLogs(int opUserId)
        {
            List<PunchObjectLibrary> logs = new List<PunchObjectLibrary>();
            using (var context = new PunchClockEntities())
            {
                //var userIds = (from u in context.tUsers
                //               join c in context.tCompanies on u.companyId equals c.companyId
                //               where u.userId != opUserId && u.userTypeId == 1
                //               select u.userId).ToList();
                var companyId = context.tUsers.Where(x=>x.userId == opUserId).Select(x=>x.companyId).FirstOrDefault();
                logs = (from p in context.tPunches
                        join u in context.tUsers on p.userId equals u.userId
                        where u.companyId == companyId
                        //userIds.Any(x=> u.userId == x)
                        && p.requestForApproval == true
                        && p.isManagerAccepted == false
                        && p.punchOut != null
                        select new PunchObjectLibrary
                        {
                            isManagerAccepted = p.isManagerAccepted,
                            punchDate = p.punchDate,
                            punchId = p.punchId,
                            punchIn = p.punchIn,
                            punchOut = p.punchOut,
                            userId = p.userId,
                            EmployeeName = u.firstName + " "+u.lastName,
                            Hours = EntityFunctions.DiffSeconds(p.punchIn, p.punchOut),
                            comments = p.comments
                        }).ToList();
            }
            return logs;
        }

        public string PunchIn(int userId, TimeSpan punchTime, string ipAddress)
        {
            string message = "Successfully punched in";
            using (var context = new PunchClockEntities())
            {
                var user = context.tUsers.Where(x => x.userId == userId).FirstOrDefault();
                tPunch punch = new tPunch
                {
                    userId = userId,
                    punchDate = DateTime.UtcNow,
                    punchIn = punchTime != TimeSpan.MinValue ? punchTime : DateTime.Now.ToUniversalTime().TimeOfDay
                };
                if (punchTime != TimeSpan.MinValue)
                {
                    if (string.IsNullOrEmpty(punch.comments))
                        punch.comments = string.Empty;
                    punch.comments += " user requested explicit punch time";
                    punch.requestForApproval = true;
                }
                if (user.userRegistered_ip != ipAddress)
                {
                    if (string.IsNullOrEmpty(punch.comments))
                        punch.comments = string.Empty;
                    punch.comments +=  "Punch from new IP address";
                    punch.requestForApproval = true;
                }
                context.tPunches.Add(punch);
                try
                {
                    context.SaveChanges();
                }
                catch (Exception ex)
                {
                    message = ex.Message;
                }
            }
            message = string.Format("<div class=\"{0}\">  <button type=\"button\" class=\"close punchCompleteMessage\" data-dismiss=\"alert\">×</button>" + message + "</div>",
              message == "Successfully punched in"
              ? "alert alert-dismissable alert-success"
              : "alert alert-dismissable alert-danger");
            return message;
        }

        public string PunchOut(int userId, int punchId, TimeSpan punchTime, string ipAddress)
        {
            string message = "Successfully punched Out";
            using (var context = new PunchClockEntities())
            {
                var user = context.tUsers.Where(x => x.userId == userId).FirstOrDefault();
                var punch = context.tPunches.Where(x => x.punchId == punchId).SingleOrDefault();
                punch.punchOut = punchTime != TimeSpan.MinValue ? punchTime : DateTime.Now.ToUniversalTime().TimeOfDay;
                if (punch.userId != userId)
                    return "Invalid operation";
                if (punchTime != TimeSpan.MinValue)
                {
                    if (string.IsNullOrEmpty(punch.comments))
                        punch.comments = string.Empty;
                    punch.comments += " User requested explicit punch time";
                    punch.requestForApproval = true;
                }
                if (DateTime.UtcNow.Date.Subtract(punch.punchDate).Days != 0)
                {
                    if (string.IsNullOrEmpty(punch.comments))
                        punch.comments = string.Empty;
                    message = punch.comments += " Due to discrepancy in punch timings, manager Approval is requested for this punch out time";
                    punch.requestForApproval = true;
                }
                if (user.userRegistered_ip != ipAddress)
                {
                    if (string.IsNullOrEmpty(punch.comments))
                        punch.comments = string.Empty;
                    punch.comments += " Punch from new IP address";
                    punch.requestForApproval = true;
                }
                try
                {
                    context.SaveChanges();
                }
                catch (Exception ex)
                {
                    message = ex.Message;
                }
            }
            message = string.Format("<div class=\"{0}\">  <button type=\"button\" class=\"close punchCompleteMessage\" data-dismiss=\"alert\">×</button>" + message + "</div>",
                message == "Successfully punched Out"
                ? "alert alert-dismissable alert-success"
                : "alert alert-dismissable alert-danger");
            return message;
        }

        public List<PunchObjectLibrary> Search(int operatingUserId, int userId, DateTime stDate, DateTime enDate)
        {
            List<PunchObjectLibrary> logs = new List<PunchObjectLibrary>();
            using (var context = new PunchClockEntities())
            {
                logs = (from p in context.tPunches
                        where p.userId == userId
                        && EntityFunctions.DiffDays(stDate, p.punchDate ) >= 0
                        && EntityFunctions.DiffDays(enDate, p.punchDate) <= 0
                        && p.punchOut != null
                        select new PunchObjectLibrary
                        {
                            isManagerAccepted = p.isManagerAccepted,
                            requestForApproval = p.requestForApproval,
                            punchDate = p.punchDate,
                            punchId = p.punchId,
                            punchIn = p.punchIn,
                            punchOut = p.punchOut,
                            userId = p.userId,
                            ApprovedHours = p.requestForApproval ? (p.isManagerAccepted == true ? EntityFunctions.DiffSeconds(p.punchIn, p.punchOut) : 0) : EntityFunctions.DiffSeconds(p.punchIn, p.punchOut),
                            Hours = EntityFunctions.DiffSeconds(p.punchIn, p.punchOut),
                            comments = p.comments
                        }).ToList();
            }
            return logs;
        }

        public bool Approve(PunchObjectLibrary punchObj, int opUserId)
        {
            bool retValue = false;
            using (var context = new PunchClockEntities())
            {
                var punch = context.tPunches.Where(x => x.punchId == punchObj.punchId).FirstOrDefault();
                punch.punchIn = punchObj.punchIn;
                punch.punchOut = punchObj.punchOut;
                punch.isManagerAccepted = punchObj.isManagerAccepted;
                punch.punchDate = punchObj.punchDate;
                punch.comments = punchObj.comments;
                try
                {
                    context.SaveChanges();
                    retValue = true;
                }
                catch (Exception)
                {
                    retValue = false;
                }
            }
            return retValue;
        }
    }
}
